package othello.model;

import othello.players.IPlayer;
import othello.players.IPlayerInfo;
import othello.players.learnplayers.AbstractNeuralNetworkPlayer.BenchmarkState;

import java.awt.Color;
import java.awt.Point;
import java.util.Iterator;
import java.util.List;

public interface IBoard {

    /**
     * @return the vertical game board dimensions.
     */
    public int getRowCount();

    /**
     * @return the horizontal game board dimensions.
     */
    public int getColCount();

    public int getMoves();
    
    public int getTurns();
    
    public int getRun();
    
    public int getRealMaxGames();
    
    public boolean getRandFirstFourMoves();

    public byte[][] getState();

    /**
     * Prior to the start of a game, joins a player to a game.
     * The board will in turn tell the player that it has joined.
     * Once the game begins, registered players are solicted for their moves
     * in turn.
     * @param p is any player that has not been registered before.
     * @param color
     */
    public void addPlayer(IPlayer p, Color color);

    /**
     * @return the set of player information (IPlayerInfo) of all the
     * registered players as an iterator.  The first item will be whomever's
     * turn it is, and then in order from there.
     * Turn order is based on registration order.
     */
    public Iterator<IPlayerInfo> getPlayers();
    public List<IPlayer> getPlayersList();

    /**
     * Initiate a set of games between the currently registered players.
     * The same players play over and over again, alternating which goes first.
     *
     * @param numGames
     */
    public void beginTournament();

    /**
     * Initialize a blank board and begin the game (by asking the first player
     * for a move).
     */
    public void beginGame();

    /**
     * @param row
     * @param col
     * @return the player that occupies the given square, or null if it is
     * unoccupied.
     */
    public Color playerAt(int row, int col);

    /**
     * @param p
     * @param row
     * @param col
     * @return the player that occupies the given square, or null if it is
     * unoccupied.
     */
    public boolean isValidMove(Color p, int row, int col);

    /**
     * This is how a player plays a piece.
     * The board will first confirm that it was indeed that player's turn.
     * @param p
     * @param row
     * @param col
     * @return true iff the move is valid.
     */
    public boolean placePiece(IPlayer p, int row, int col);

    /**
     * If a player cannot play a valid move, they must pass.
     * The implementation can decide whether or not to allow them to pass when
     * they don't have to.
     * @param p
     * @return true iff the player has been allowed to pass.
     */
    public boolean pass(IPlayer p);
    
    public int getGamesLeft();

    /**
     * @param p
     * @param row
     * @param col
     * @return a copy of this board, modified as if the player had played at
     * the specified square.  Very handy for evaluating potential moves.
     */
    public IBoard hypotheticallyPlacePiece(Color p, int row, int col);

    /**
     * @param p
     * @return the current score given a player's color.
     */
    public int playerScore(Color p);

    /**
     * @return true iff the board considers the game over.
     * It will no longer accept any moves after that point.
     * The game is over when either the board is completely full,
     * or when both players pass (either because they must or they choose to).
     */
    public boolean isGameOver();

    /**
     * @return a string detailing the current player's score in the middle of
     * a game.  If the game is over, return null.
     */
    public String getCurrentPlayerScore();

    /**
     * @return the color of the current player.
     * If the game is over, return null.
     */
    public Color getCurrentPlayerColor();

    /**
     * @return a string detailing the outcome of the game.
     * If the game is ongoing, return null.
     */
    public String getGameScore();

    /**
     * @return a string detailing the outcome (or present status) of the
     * tournament.  This string will not be null, even if getGameScore is.
     */
    public String getTournamentScore();

    /**
     * @return the coordinates of the last move someone made.
     * Return null if the last move was to pass, or was the beginning of the game.
     */
    public Point lastMove();

	public BenchmarkState getBenchmarkstate();
	

	//~ public void initializeTrainingMoves();	

	
}
